#pragma once
#include <memory>
#include <mutex>
#include <vector>
#include "Channel.h"

namespace xncc {
namespace sys {
    class EventFd;
}
namespace foundation {
    class WakeupChannel final : public Channel
    {
      public:
        WakeupChannel(EventLoop* loop, std::unique_ptr<xncc::sys::EventFd> wakeupFd);

        explicit WakeupChannel(EventLoop* loop);
        ~WakeupChannel() override = default;

        WakeupChannel(const WakeupChannel&)             = delete;
        WakeupChannel(const WakeupChannel&&)            = delete;
        WakeupChannel& operator=(const WakeupChannel&)  = delete;
        WakeupChannel& operator=(const WakeupChannel&&) = delete;

        auto Type() -> ChannelType::value override { return ChannelType::WAKEUP_CHANNEL; }
        void addPendingFuncs(types::Task func);
        void handleRead() override;
        void doPendingFuncs();

        bool isRuningPendingFunctors() const { return callingPendingFunctors_; }

      private:
        void wakeup();
        bool readfd();

        bool                                callingPendingFunctors_ = false;
        std::mutex                          mutex_;
        std::vector<types::Task>            pendingFunctors_;
        std::unique_ptr<xncc::sys::EventFd> wakeupFd_               = nullptr;
        static constexpr int                NOBLOCKPOLLER_WAKEUP_FD = -1;
    };
}  // namespace foundation
}  // namespace xncc